This guide demonstrates two use cases for leveraging built-in actions and auto-tagging features in Palo Alto Networks PAN-OS to automate security responses.
I'm going to demonstrate leveraging the built-in actions in PAN-OS to tag a destination that fails decryption. Additionally, I will use the built-in action to quarantine potentially infected hosts (covered in Use Case 2).
This functionality is built into PAN-OS and is available for anyone to use. Essentially, we monitor the logs, create a filter, and if the filter criteria are met, we trigger a built-in action.
We can tag the destination or source IP address. We can also specify a duration for the tag: it can be permanent or temporary, for example, for an hour. This allows for flexibility, so let your creativity guide you. Essentially, anything identifiable in the logs can be used as a trigger for tagging.
I will now navigate to the 'Objects' tab and then to 'Tags'.
As you can see, I have a tag named
decrypt-error
. I'll open it. Notice I've assigned a red-orange color and added 'SSL Forward Proxy error' in the comments. The important part is the tag name:
decrypt-error
.
Next, let's go to 'Address Groups' and examine the dynamic address group (DAG) I created, named 'Decryption Bypass'. As you can see, it's configured to match the
decrypt-error
tag.
Now, I will navigate to the 'Log Forwarding' section of my firewall. As shown, I have already created a log forwarding profile.
Let's take a closer look. I've created an entry here called 'decrypt-bypass'.
Opening it up, you can see I'm targeting the 'Traffic' log type and have built a filter. This filter is configured to match if 'session end reason' equals 'decrypt-unsupported-parameter', OR 'session end reason' equals 'decrypt-error', OR 'session end reason' equals 'decrypt-cert-validation-err'. If any of these conditions match... and I can actually use this dropdown:
...in my filter builder here to view the live logs on this firewall.
Okay, it will perform the search, and as you can see, there are some matches. This confirms my filter is working correctly. Now, for the 'Built-in Actions' part, which is key to this setup.
So, right here, I've created an action named 'decrypt-bypass'. Let's examine its configuration.
Recall that my use case is to tag the destination address. Imagine a workstation attempts to access a resource on the internet.
I am decrypting all my traffic, and for some reason, one of those 'session end reasons' (e.g., 'decrypt-error') occurs. In such a case, I want to add a tag to the destination address.
The tag will be
decrypt-error
. As I've already shown, this
decrypt-error
tag is used in a dynamic address group. We'll revisit that shortly.
I have set the timeout for this tag to 15 minutes, but you can set this to zero for an indefinite period, 60 minutes, or any other duration you prefer.
After clicking 'OK', it's worth noting that other actions are available. Tagging the destination and bypassing decryption is useful, but you would need to monitor frequently to see what's being bypassed.
To enhance this, you could also configure an HTTP GET request to an integrated server to open a ticket, send an email notification, or trigger an SNMP trap. These provide additional ways to be alerted.
Essentially, these actions notify you that an event occurred. What Patrick and I are demonstrating is how to identify an event in the logs and then take an automated action, such as excluding it from decryption or, as Patrick will show, blocking its internet access.
Alright, this configuration looks good. To summarize, up to this point, we have created a tag, a dynamic address group, a filter, and a log forwarding profile.
We then leveraged that tag for the built-in action. The next step is to configure the policies. I'll navigate to the Decryption policy. Let me show you my configuration. The first rule, 'No Decrypt', specifies that for traffic from 'inside' to 'outside' destined for URL categories like Financial Services, Government, Health and Medical, Military, and Shopping, no decryption should be performed. I don't want to decrypt any of these.
These are URL categories often excluded for privacy or compliance reasons, like PCI. This aligns with our best practice guide. The second decryption policy rule is named 'Decrypt-Bypass', and as you can see, its action is also set to 'No Decrypt'.
But note what I'm referencing as the destination: 'Decryption-Bypass'. This is our dynamic address group (DAG).
Below that is the actual decryption rule. For this demonstration, 'Decrypt-Lab' (and I also have 'Decrypt-Home'), I'm referencing one of my devices on the network—my iPad—as the source.
So, to reiterate, if traffic originates from the inside, goes to the outside, and is destined for one of the IP addresses that gets tagged (and thus added to our 'Decryption-Bypass' DAG), it will be excluded from decryption.
Okay, so now I'll navigate back to 'Objects', then 'Address Groups'. I want to show you that currently, there are no members in this 'Decryption-Bypass' dynamic address group.
Now, I will visit a website that is known to cause a decryption error, which will trigger our configured automation. I'll do that now... Okay, awesome. Let's navigate to see the results.
Let's check the 'Addresses' section of the DAG again. As you can see, because I visited that problematic site, its IP address was tagged and is now listed here. It's now excluded from decryption. I believe I set the timeout for 15 minutes. So, for the next 15 minutes, any user trying to access this specific IP address will not have their traffic decrypted. This happened because, as per my filter, a 'session end reason' such as 'decrypt-error' was triggered.
Yes, it matched one of the multiple factors I included in the filter. That's essentially it for this use case. I've seen large companies leverage this method because achieving full decryption can be challenging. You can't simply enable decryption for everyone and expect it to work flawlessly. It's typically a phased approach. Even when you start decrypting for specific user groups or subnets, you'll inevitably encounter issues due to certificate pinning or other application-specific behaviors.
If you've ever implemented decryption, you understand the potential for applications to break, requiring you to sift through logs to identify problematic destinations. This automated tagging approach can be very helpful in pinpointing exactly which destinations are causing issues, thereby streamlining the troubleshooting process. Exactly.
So, I'm going to stop sharing now, and Patrick will share his lab to walk us through his use case.
Patrick:
Okay, so before I go to the firewall, I want to briefly review DNS sinkholing. Imagine an infected host on your network (Host A on the left). This host wants to communicate with a command-and-control (C2) server,
dfb.7rz.ru
(top right), which sounds suspicious. To do this, Infected Host A sends a DNS query to resolve the IP address of this domain. Malicious domains often change IP addresses to evade blocklists, so they rely on DNS. The query goes to the local DNS server. If the local DNS server doesn't know the IP address for
dfb.7rz.ru
, it forwards the query to a remote DNS server.
However, the firewall, positioned to inspect this traffic, has a database of malicious DNS signatures. When it detects a query for a known malicious domain, instead of letting it go to the remote DNS server, the firewall can respond with a sinkhole IP address. This sinkhole IP (shown as 1.2.3.4 here, but configurable) is then returned to the local DNS server, and subsequently to the infected host. The infected host receives this bogus IP address and is thus unable to contact the actual C2 server.
For my use case, I'm not focused on tagging destinations like in the previous example. Instead, I want to quarantine the *source*—the potentially infected hosts on my network. I aim to put them into a group and control their traffic until I can remediate them and remove any malware.
Okay, so now we're looking at my firewall, which is running PAN-OS 9.1. The first place I'll go is to 'Objects'.
I have a very basic configuration on this firewall that allows outbound traffic. As you can see, I've also configured an Anti-Spyware profile, which I will later add to my security policy rule.
First, I'll go to 'Address Groups' and create a new dynamic address group (DAG). I'll name this 'Infected-Hosts'. Then, I'll set its type to 'Dynamic', similar to the previous example.
Next, I'll add match criteria. In this case, I'm going to use a tag named 'infected-host'.
Alright, so that's the first step. I already have my tags pre-configured. Now, I'll navigate to 'Log Forwarding' and add a new log forwarding profile.
I'll name this 'Infected-Host-LF' (for Log Forwarding) or similar. Then, down here, I'll configure the tagging. I'll create an entry, perhaps named 'Tag-Infected-Host', to clearly define its purpose.
So we can differentiate, I'm going to use the 'Threat' log type for this profile.
And then, I'll build a filter.
I'll build my filter for a very specific criterion.
I want to filter for log entries where the 'action' equals 'sinkhole'. I'll add that condition here.
Alright. I could view the filtered logs now, but I likely won't see anything yet because I haven't activated the DNS sinkholing feature that generates these specific logs. This will be useful after testing. So, I'll click 'OK'. Now that the log forwarding profile match list is built...
...I need to configure the 'Built-in Actions' within this log forwarding profile.
So, I'll click 'Add'. I can name this action, for example, 'Tag-Source-Infected'. For the action itself, I'm going to select 'Tag'. I want to tag the 'Source Address'. The tag will be 'infected-host' (which I created earlier), and it's a 'Local' tag. Alright, so now...
...when a DNS sinkhole event is logged (matching our filter), the source IP address of that traffic will be tagged with 'infected-host'. This tag will then cause the IP address to be dynamically added to our 'Infected-Hosts' DAG. The next steps involve configuring the DNS sinkhole itself. I'll go to my Anti-Spyware profile (which I've pre-built) and navigate to the 'DNS Signatures' tab.
Now, I need to apply this to an External Dynamic List (EDL) containing malicious domains, or use Palo Alto Networks provided DNS Security signatures. For this demo, I'll use an existing rule or add one. I'll select my list (e.g., 'DNS-Sinkhole-List') and set its action to 'sinkhole'.
For the sinkhole IP address, I'm not concerned with IPv6 in this lab, so I'll use the IPv4 sinkhole address. I'll leave it as the default Palo Alto Networks sinkhole address:
sinkhole.paloaltonetworks.com
. We'll see this address in action later. Now that DNS sinkholing is configured within the Anti-Spyware profile, the final steps involve applying this to a security policy. I'll go to my 'Policies' and edit my outbound ('egress-outside') security rule.
This is my basic outbound rule. I will add my 'Anti-Spyware' profile to it. Then, under 'Actions', I'll select the 'Log Forwarding' profile I created ('Infected-Host-LF').
Okay, the final step is to create a new security policy rule to quarantine these tagged devices. I'll clone my existing outbound rule, move it to the top, and modify it.
There are many ways to implement the quarantine.
I'll name this rule 'Block-Infected-Devices' or 'Quarantine-Infected-Devices'. I can also change the color tag for visibility. The key change is the 'Source Address': I will set this to my dynamic address group, 'Infected-Hosts'. The destination will remain 'outside' (or 'any').
'Application' can be set to 'any' since the action will be 'deny'. I'll remove any security profiles from this rule as they are not needed for a deny rule. The action for this rule will be 'Deny'. This will be a simple deny rule. Again, I don't have to be this broad; I could configure it more granularly to, for example, only block access to critical servers or specific services. But for this demonstration, a complete block is sufficient. Okay, so now...
...that this rule is set up, I will hit 'Commit'. While we're waiting for the commit, let me show you the External Dynamic List (EDL) I'm using for testing. It's a very basic list containing just three domain names, which are actual examples from malware lists:
golfsource.us
,
tourindia.ion
, and
vip-projects.org
.
So, once the commit is complete, I can perform an
nslookup
for one of these domains to see what IP address is returned.
It should be the sinkhole IP address we configured.
Alright, the next step is to test it using
nslookup
from a client machine behind the firewall.
I'll use one of the domains from my EDL, for example,
golfsource.us
.
Okay, the
nslookup
for
golfsource.us
returns
sinkhole.paloaltonetworks.com
with the IP address 72.5.65.111, which is the Palo Alto Networks sinkhole address. It also shows an alias of
golfsource.us
. Now, let's try another one,
tourindia.ion
...
...and it's timing out. Instead of resolving via DNS, it's now completely blocked. Why? Because after the first sinkhole event for
golfsource.us
, the source IP of my test machine was tagged and added to the 'Infected-Hosts' DAG. This caused its traffic to match our top 'Block-Infected-Devices' security rule. If I check the 'Infected-Hosts' DAG members now...
...I can see that my device's IP, 192.168.1.2, is now registered as a source address in this 'Infected-Hosts' DAG. Consequently, all its traffic is being denied by our top rule. That's a successful test. To further verify, we can look at the 'Monitor' tab. In the 'Threat' log, we should see the initial sinkhole event for
golfsource.us
. For the
tourindia.ion
attempt...
...we'd need to check the 'Traffic' log to see it being blocked by our 'Block-Infected-Devices' rule, because at that point, the host was already quarantined. All traffic from this workstation is now blocked, effectively quarantining it. It can't go anywhere. And that's how you set up automated source quarantine using DNS sinkholing and dynamic tagging.